package com.ibm.tivoli.swat.tsam_ec2.tsam;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.security.KeyStore;
import java.text.ParseException;
import java.util.ArrayList;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.ext.RuntimeDelegate;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.ibm.tivoli.swat.tsam_ec2.tsam.model.TSAMImage;
import com.ibm.tivoli.swat.tsam_ec2.tsam.model.TSAMImageImpl;
import com.ibm.tivoli.swat.tsam_ec2.tsam.model.TSAMInstance;
import com.ibm.tivoli.swat.tsam_ec2.tsam.model.TSAMInstanceImpl;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import com.sun.jersey.client.urlconnection.HTTPSProperties;
import com.sun.jersey.core.util.MultivaluedMapImpl;

public class TSAMWebServiceClient {
	private static final String TSAM_USERNAME = "maxadmin";
	private static final String TSAM_PASSWORD = "maxadmin";

	private static final String IMAGE_STATE = "OK";
	private static final String MONITORING_STATE = "Unmonitored";
	private static final String PROJECT_NAME = "Integration Project";
	private static final String INDEFINITE = "9999-12-30T00:00:00-05:00";
	private static final String TEAM_NAME = "SUCH";

	private WebResource service;
	private XMLParser parser;

	private static final TSAMWebServiceClient singleton = new TSAMWebServiceClient();

	private static HostnameVerifier getHostnameVerifier() {
		HostnameVerifier verifier = new HostnameVerifier() {
			public boolean verify(String urlHostname, SSLSession certHostname) {
				return true;
			}
		};
		return verifier;
	}

	private static SSLContext getSSLContext() throws Exception {
		File file = new File("jssecacerts");
		if (file.isFile() == false) {
			char SEP = File.separatorChar;
			File dir = new File(System.getProperty("java.home") + SEP + "lib"
					+ SEP + "security");
			file = new File(dir, "jssecacerts");
			if (file.isFile() == false) {
				file = new File(dir, "cacerts");
			}
		}
		System.out.println("Loading KeyStore " + file + "...");
		InputStream in = new FileInputStream(file);

		char[] passphrase = "changeit".toCharArray();
		KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
		ks.load(in, passphrase);

		SSLContext context = SSLContext.getInstance("TLS");
		TrustManagerFactory tmf = TrustManagerFactory
				.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		tmf.init(ks);
		X509TrustManager defaultTrustManager = (X509TrustManager) tmf
				.getTrustManagers()[0];
		SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
		context.init(null, new TrustManager[] { tm }, null);
		return context;
	}

	private static URI getBaseURI() {
		return UriBuilder.fromUri(
				"https://tsam721.tivlab.raleigh.ibm.com:9443/maxrest/rest/os")
				.build();
	}

	private void createWebResource() throws Exception {
		ClientConfig config = new DefaultClientConfig();

		HTTPSProperties properties = new HTTPSProperties(getHostnameVerifier(),
				getSSLContext());
		config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
				properties);
		Client client = Client.create(config);
		client.addFilter(new HTTPBasicAuthFilter(TSAM_USERNAME, TSAM_PASSWORD));
		service = client.resource(getBaseURI());
	}

	private void initializeParser() {
		parser = XMLParser.getInstance();
	}

	private TSAMWebServiceClient() {
		try {
			createWebResource();
			initializeParser();
		} catch (Exception exception) {
			System.err.println("TSAMWebServiceClient error: " + exception);
		}
	}

	public static TSAMWebServiceClient getInstance() {
		return singleton;
	}

	private Node findChildNodeByName(Element node, String name) {
		NodeList nodes = node.getChildNodes();
		for (int i = 0; i < nodes.getLength(); i++) {
			Node child = nodes.item(i);
			if (child.getNodeName().equals(name)) {
				return child;
			}
		}
		return null;

	}

	private String findChildNodeContentByName(Element node, String name) {
		Node result = findChildNodeByName(node, name);
		return result == null ? "" : result.getTextContent();
	}

	private Element processResponse(ClientResponse response)
			throws TSAMWebServiceClientException {
		System.out.println("response: " + response);
		String tag = response.getEntity(String.class);
		System.out.println("tag: " + tag);

		Document document;
		try {
			document = parser.parse(tag);
			Element root = document.getDocumentElement();
			return root;
		} catch (ParserConfigurationException e) {
			throw new TSAMWebServiceClientException(e);
		} catch (SAXException e) {
			throw new TSAMWebServiceClientException(e);
		} catch (IOException e) {
			throw new TSAMWebServiceClientException(e);
		}
	}

	private Element get(WebResource request)
			throws TSAMWebServiceClientException {
		System.out.println("request: " + request);
		ClientResponse response = request.get(ClientResponse.class);
		return processResponse(response);
	}

	private Element post(WebResource request)
			throws TSAMWebServiceClientException {
		try {
			return processResponse(request.post(ClientResponse.class));
		} catch (UniformInterfaceException e) {
			throw new TSAMWebServiceClientException(e);

		}
	}

	public ArrayList<TSAMImage> describeImages()
			throws TSAMWebServiceClientException {
		// RuntimeDelegate.setInstance(new TSAMRuntimeDelegateImpl ());
		RuntimeDelegate instance = RuntimeDelegate.getInstance();
		System.out
				.println("TSAMWebServiceClient.describeInstance runtime delegate: "
						+ instance);
		WebResource request = service.path("TPV02IMGLIBENTRYMSTR").queryParam(
				"fd", "PMZHBT_ILMSTRIMG");
		// .queryParam("POOL_IDENTIFIER", "%2Fcloud%2Frest%2Fpools%2F7");
		Element root = get(request);
		System.out.println("TSAMWebServiceClient.describeInstance response: "
				+ DomUtil.elementToString(root));
		Element set = (Element) (root.getChildNodes().item(0));
		NodeList nodes = set.getChildNodes();
		ArrayList<TSAMImage> list = new ArrayList<TSAMImage>();
		System.out.println("NodeList length: " + nodes.getLength());
		for (int i = 0; i < nodes.getLength(); i++) {
			Element entry = (Element) (nodes.item(i));
			String name = findChildNodeContentByName(entry, "NAME");
			String imageId = findChildNodeContentByName(entry,
					"SOFTWARE_STACK_ID");
			String createdBy = findChildNodeContentByName(entry, "CREATED_BY");
			String poolIdentifier = findChildNodeContentByName(entry,
					"POOL_IDENTIFIER");
			list.add(new TSAMImageImpl(imageId, IMAGE_STATE, createdBy, name,
					poolIdentifier));
		}
		return list;
	}

	private Element getFirstChild(Element element) {
		return (Element) (element.getChildNodes().item(0));
	}

	public ArrayList<TSAMInstance> describeInstances()
			throws TSAMWebServiceClientException {
		WebResource request = service.path("PMZHBR1_PMRDPSIVIEW");
		// .queryParam("STATUS", "OPERATION");
		ArrayList<TSAMInstance> list = new ArrayList<TSAMInstance>();
		try {
			Element root = get(request);
			System.out.println("TSAMWebServiceClient.describeInstances root: "
					+ DomUtil.elementToString(root));
			Element set = getFirstChild(root);
			NodeList nodes = set.getChildNodes();
			System.out
					.println("TSAMWebServiceClient.describeInstances NodeList length: "
							+ nodes.getLength());
			for (int i = 0; i < nodes.getLength(); i++) {
				Element entry = (Element) (nodes.item(i));
				String vmName = findChildNodeContentByName(entry, "VSNAME");
				if (vmName.equals("")) {
					// vmName = findChildNodeContentByName(entry, "PMZHBWTNID");
				}
				String reservationId = findChildNodeContentByName(entry,
						"PMZHBWTNID");
				String name = findChildNodeContentByName(entry, "NAME");
				String owner = findChildNodeContentByName(entry, "SERVICEOWNER");
				System.out
						.println("TSAMWebServiceClient.describeInstances  owner: "
								+ owner);
				String status = findChildNodeContentByName(entry, "STATUS");
				String imageId = findChildNodeContentByName(entry,
						"PMZHBSSVCIID");
				String instanceId = findChildNodeContentByName(entry,
						"PMZHBWTNID");
				String instanceType = findChildNodeContentByName(entry,
						"VSTYPE");
				String startTime = findChildNodeContentByName(entry,
						"PROJSTARTTIME");
				String availabilityZone = findChildNodeContentByName(entry,
						"VSRESGRPNUM");

				list.add(new TSAMInstanceImpl(reservationId, owner, name,
						status, vmName, imageId, instanceId, instanceType,
						DateUtil.convertDate(startTime), MONITORING_STATE,
						availabilityZone));
			}
			return list;
		} catch (ParseException e) {
			throw new TSAMWebServiceClientException(e);
		} catch (DatatypeConfigurationException e) {
			throw new TSAMWebServiceClientException(e);
		}

	}

	private String obtainSRId(Element root) {
		Element set = getFirstChild(root);
		Element cr = getFirstChild(set);
		return findChildNodeContentByName(cr, "PMSCCRNUM");
	}

	public class Instance {
		public String instanceId;
		public String serviceInstanceId;
		public String projectName;
		public String hostName;
	}

	public Instance obtainInstanceInfo(String instanceId)
			throws TSAMWebServiceClientException {
		WebResource request = service.path("PMZHBR1_PMRDPSIVIEW").queryParam(
				"PMZHBWTNID", instanceId);
		Element root = get(request);
		System.out
				.println("TSAMWebServiceClient.obtainServiceInstanceId response : "
						+ DomUtil.elementToString(root));

		Element set = getFirstChild(root);
		Element view = getFirstChild(set);
		Instance instance = new Instance();
		instance.instanceId = instanceId;
		instance.serviceInstanceId = findChildNodeContentByName(view,
				"PMZHBSSVCIID");
		instance.projectName = findChildNodeContentByName(view, "NAME");
		instance.hostName = findChildNodeContentByName(view, "VSNAME");
		return instance;

	}

	private String createSR(String description)
			throws TSAMWebServiceClientException {
		// https://tsam721.tivlab.raleigh.ibm.com:9443/maxrest/rest/os/SRM_CARDCREATE?
		// DESCRIPTION=Restart%20Server%20VM009042008149&_compact=1&_format=json
		WebResource request = service.path("SRM_CARDCREATE").queryParam(
				"DESCRIPTION", description);
		Element root = post(request);
		System.out.println("TSAMWebServiceClient.createSR response : "
				+ DomUtil.elementToString(root));
		String srId = obtainSRId(root);
		System.out.println("TSAMWebServiceClient.createSR SR Id : " + srId);
		return srId;
	}

	public String obtainClassStructureId(String classificationId)
			throws TSAMWebServiceClientException {
		WebResource request = service.path("MXCLASSIFICATION").queryParam(
				"CLASSIFICATIONID", classificationId);
		Element root = get(request);
		Element set = getFirstChild(root);
		Element classStructure = getFirstChild(set);
		return findChildNodeContentByName(classStructure, "CLASSSTRUCTUREID");
	}

	class Ticket {
		String ticketId;
		String ticketUid;
	}

	private Ticket obtainTicket(Element root) {
		Element set = getFirstChild(root);
		Element sr = getFirstChild(set);
		Ticket ticket = new Ticket();
		ticket.ticketId = findChildNodeContentByName(sr, "TICKETID");
		ticket.ticketUid = findChildNodeContentByName(sr, "TICKETUID");
		return ticket;
	}

	// Populates CLASSSTRUCTUREID, COMMODITY, COMMODITYGROUP, CREATEDBY,
	// ITEMSETID, ORDERUNIT, PMSCCRID, REPORTEDBY
	private MultivaluedMap<String, String> createSRMap(String classificationId,
			String srId, String description, String itemNum)
			throws TSAMWebServiceClientException {
		String classStructureId = obtainClassStructureId(classificationId);
		MultivaluedMap<String, String> map = new MultivaluedMapImpl();
		map.add("CLASSSTRUCTUREID", classStructureId);
		map.add("COMMODITY", "VSERVER");
		map.add("COMMODITYGROUP", "SRVAUTOM");
		map.add("CREATEDBY", TSAM_USERNAME);
		map.add("ITEMSETID", "PMSCS1");
		map.add("ORDERUNIT", "EACH");
		map.add("PMSCCRID", srId);
		map.add("REPORTEDBY", "PMRDPCAUSR");
		map.add("DESCRIPTION", description);
		map.add("ITEMNUM", itemNum);
		map.add("PMSCITEMNUM", itemNum);
		map.add("QTY", "1");
		return map;
	}

	private Ticket postSR(MultivaluedMap<String, String> map)
			throws TSAMWebServiceClientException {
		WebResource request = service.path("SRM_SRCREATE").queryParams(map);
		Element root = post(request);
		System.out.println("TSAMWebServiceClient.createSR response : "
				+ DomUtil.elementToString(root));
		Ticket ticket = obtainTicket(root);
		System.out.println("TSAMWebServiceClient.createSR ticketUId : "
				+ ticket.ticketUid);
		return ticket;

	}

	private Ticket updateRebootInstanceSR(Instance instance, String srId)
			throws TSAMWebServiceClientException {
		// https://tsam721.tivlab.raleigh.ibm.com:9443/maxrest/rest/os/SRM_SRCREATE?
		// CLASS=SR&CLASSSTRUCTUREID=8100232&COMMODITY=VSERVER&COMMODITYGROUP=SRVAUTOM&
		// CREATEDBY=PMRDPCAUSR&DESCRIPTION=Restart%20Server%20VM009042008149&ITEMNUM=PMRDP_0257A_72&
		// ITEMSETID=PMSCS1&ORDERUNIT=EACH&PMSCCRID=1251&PMSCITEMNUM=PMRDP_0257A_72&QTY=1&
		// REPORTEDBY=PMRDPCAUSR&_compact=1&_format=json

		MultivaluedMap<String, String> map = createSRMap("PMRDP_SR_SERVEROP",
				srId, "Restart Server " + instance.projectName, "PMRDP_0257A_72");
		return postSR(map);
	}

	private void postUpdateTicket(Ticket ticket, QueryParam param)
			throws TSAMWebServiceClientException {
		WebResource request = service.path("SRM_SRCREATE/" + ticket.ticketUid)
				.queryParams(param.getMap());
		Element root = post(request);
		System.out.println("TSAMWebServiceClient.createSR response : "
				+ DomUtil.elementToString(root));

	}

	private void updateRebootInstanceTicket(Instance instance, String srId,
			Ticket ticket) throws TSAMWebServiceClientException {
		// https://tsam721.tivlab.raleigh.ibm.com:9443/maxrest/rest/os/SRM_SRCREATE/222?
		// PMSCCRID=1251&SOURCE=TSAMWEBUI&TICKETID=1222&
		// TICKETSPEC.1.ASSETATTRID=PMRDPCLCPR_SERVICEINSTANCEID&TICKETSPEC.1.NUMVALUE=121&
		// TICKETSPEC.1.REFOBJECTID=222&TICKETSPEC.1.SECTION=&TICKETSPEC.1.TICKETSPECID=4709&
		// TICKETSPEC.2.ALNVALUE=RESTARTSRV&TICKETSPEC.2.ASSETATTRID=PMRDPCLVSRV_MPNUM&
		// TICKETSPEC.2.REFOBJECTID=222&TICKETSPEC.2.SECTION=&TICKETSPEC.2.TICKETSPECID=4710&
		// TICKETSPEC.3.ASSETATTRID=PMRDPCLCVS_VSNODEID&TICKETSPEC.3.NUMVALUE=794&
		// TICKETSPEC.3.REFOBJECTID=222&TICKETSPEC.3.SECTION=&TICKETSPEC.3.TICKETSPECID=4711&
		// TICKETSPEC.4.ALNVALUE=RESTART&TICKETSPEC.4.ASSETATTRID=PMRDPOPTYPE&
		// TICKETSPEC.4.REFOBJECTID=222&TICKETSPEC.4.SECTION=&TICKETSPEC.4.TICKETSPECID=4712&
		// TICKETUID=222&_compact=1&_format=json
		QueryParam param = new QueryParam(srId, ticket);
		param.addTicketSpec("PMRDPCLCPR_SERVICEINSTANCEID", "NUMVALUE",
				instance.serviceInstanceId);
		param.addTicketSpec("PMRDPCLVSRV_MPNUM", "ALNVALUE", "RESTARTSRV");
		param.addTicketSpec("PMRDPCLCVS_VSNODEID", "NUMVALUE",
				instance.instanceId);
		param.addTicketSpec("PMRDPOPTYPE", "ALNVALUE", "RESTART");
		postUpdateTicket(ticket, param);
	}

	public void rebootInstance(String instanceId)
			throws TSAMWebServiceClientException {
		Instance instance = obtainInstanceInfo(instanceId);
		String srId = createSR("Restart Server " + instance.projectName);
		Ticket ticket = updateRebootInstanceSR(instance, srId);
		updateRebootInstanceTicket(instance, srId, ticket);
	}

	private Ticket updateCreateProjectSR(String srId, String description)
			throws TSAMWebServiceClientException {

		// https://tsam721.tivlab.raleigh.ibm.com:9443/maxrest/rest/os/SRM_SRCREATE?CLASS=SR&
		// CLASSSTRUCTUREID=8100210&COMMODITY=VSERVER&COMMODITYGROUP=SRVAUTOM&CREATEDBY=PMRDPCAUSR&
		// DESCRIPTION=Create%20Project%20with%20VMware%20Servers%20Test%20from%20SimpleSRM&
		// ITEMNUM=PMRDP_0201A_72&ITEMSETID=PMSCS1&ORDERUNIT=EACH&PMSCCRID=1289&PMSCITEMNUM=PMRDP_0201A_72&
		// QTY=1&REPORTEDBY=PMRDPCAUSR&TARGETFINISH=2011-04-21T06%3A19%3A00-04%3A00&
		// TARGETSTART=2011-04-07T06%3A15%3A06-04%3A00&_compact=1&_format=json

		// Populates COMMODITY, COMMODITYGROUP, CREATEDBY, ITEMSETID, ORDERUNIT,
		// PMSCCRID, REPORTEDBY
		MultivaluedMap<String, String> map = createSRMap(
				"PMRDP_SR_CREATE_PROJECT_VMWARE_SERVER", srId, description,
				"PMRDP_0201A_72");
		map.add("TARGETSTART", DateUtil.getTargetStart());
		map.add("TARGETEND", INDEFINITE);
		return postSR(map);
	}

	public String findIntegrationProject() throws TSAMWebServiceClientException {
		WebResource request = service.path("PMZHBR1_PMRDPSIVIEW").queryParam(
				"NAME", PROJECT_NAME);
		Element root = get(request);
		System.out
				.println("TSAMWebServiceClient.obtainServiceInstanceId response : "
						+ DomUtil.elementToString(root));
		Element set = getFirstChild(root);
		Element view = getFirstChild(set);
		if (view == null) {
			return null;
		}
		return findChildNodeContentByName(view, "PMZHBSSVCIID");
	}

	private void updateRunInstanceTicket(String srId, Ticket ticket,
			String imageId, String mpNum, String serviceInstanceId)
			throws TSAMWebServiceClientException {
		QueryParam param = new QueryParam(srId, ticket);
		param.addTicketSpec("PMRDPCLCPR_SERVICEINSTANCEID", "NUMVALUE",
				serviceInstanceId);
		param.addTicketSpec("PMRDPCLCPR_SERVICEDEFINITIONREVISION", "NUMVALUE",
				"4");
		param.addTicketSpec("PMRDPCLCPR_SERVICEDEFINITIONNUM", "ALNVALUE",
				"RDPVS");
		param.addTicketSpec("PMRDPCLVSRV_MPNUM", "ALNVALUE", mpNum);
		param.addTicketSpec("PMRDPCLCPR_PROJECTNAME", "ALNVALUE", PROJECT_NAME);
		param.addTicketSpec("PMRDPCLCPR_DESCRIPTION", "ALNVALUE", "");
		param.addTicketSpec("PMRDPCLCPR_SERVERQTY", "NUMVALUE", "1");
		param.addTicketSpec("PMRDPCLCVS_MEMORY", "NUMVALUE", "100");
		param.addTicketSpec("PMRDPCLCVS_NUMBER_CPUS", "NUMVALUE", "1");
		param.addTicketSpec("PMRDPCLCVS_NUMBER_PCPUS", "NUMVALUE", "1");
		param.addTicketSpec("PMRDPCLCVS_STORAGE_SIZE", "NUMVALUE", "15");
		param.addTicketSpec("PMRDPCLSWS_IMAGEID", "NUMVALUE", imageId);
		param.addTicketSpec("PMRDPCLCVS_SWAP_SIZE", "NUMVALUE", "0");
		param.addTicketSpec("PMRDPCLCVS_RESGRPNUM", "ALNVALUE",
				"/cloud/rest/pools/7/");
		param.addTicketSpec("PMRDPCLCPR_PERSONGROUP", "ALNVALUE", TEAM_NAME);
		param.addTicketSpec("PMRDPCLCVS_TYPE", "ALNVALUE", "VMware");
		param.addTicketSpec("PMRDPCLVSRV_NOTIFY_MPNUM", "ALNVALUE",
				"NOTIFYPENDINGDELETEPR");
		param.addTicketSpec("PMRDPCLVSRV_DELETE_MPNUM", "ALNVALUE",
				"CANPROJECT");
		param.addTicketSpec("PMRDPCLCPR_SAVE_IMAGES_ON_EXIT", "ALNVALUE",
				"false");
		param.addTicketSpec("PMRDPCLCPR_KEEP_EXISTING_IMAGES_ON_EXIT",
				"ALNVALUE", "false");
		postUpdateTicket(ticket, param);
	}

	private void createProject(String imageId)
			throws TSAMWebServiceClientException {
		String description = "Create Projet with VMware Servers "
				+ PROJECT_NAME;
		String srId = createSR(description);
		Ticket ticket = updateCreateProjectSR(srId, description);
		updateRunInstanceTicket(srId, ticket, imageId, "NEWPROJECT", "");
	}

	// https://tsam721.tivlab.raleigh.ibm.com:9443/maxrest/rest/os/SRM_SRCREATE?CLASS=SR&
	// CLASSSTRUCTUREID=8100221&COMMODITY=VSERVER&COMMODITYGROUP=SRVAUTOM&CREATEDBY=PMRDPCAUSR&
	// DESCRIPTION=Add%20VMware%20Servers%20C%C3%A9sar%20Ch%C3%A1vez%20Day&ITEMNUM=PMRDP_0211A_72&
	// ITEMSETID=PMSCS1&ORDERUNIT=EACH&PMSCCRID=1305&PMSCITEMNUM=PMRDP_0211A_72&QTY=1&
	// REPORTEDBY=PMRDPCAUSR&_compact=1&_format=json
	private Ticket updateAddServerSR(String srId, String description)
			throws TSAMWebServiceClientException {

		MultivaluedMap<String, String> map = createSRMap(
				"PMRDP_SR_ADD_VMWARE_SERVER", srId, description,
				"PMRDP_0211A_72");
		map.add("TARGETSTART", DateUtil.getTargetStart());
		map.add("TARGETEND", INDEFINITE);
		return postSR(map);
	}

	private void addServer(String instanceId, String imageId)
			throws TSAMWebServiceClientException {
		String description = "Add VMware Servers " + PROJECT_NAME;
		String srId = createSR(description);
		Ticket ticket = updateAddServerSR(srId, description);
		updateRunInstanceTicket(srId, ticket, imageId, "ADDSERVER", instanceId);

	}

	public void runInstance(String imageId)
			throws TSAMWebServiceClientException {
		String instanceId = findIntegrationProject();
		if (instanceId == null) {
			createProject(imageId);
		} else {
			addServer(instanceId, imageId);
		}
	}

	private Ticket updateTerminateInstanceSR(Instance instance, String srId)
			throws TSAMWebServiceClientException {
		MultivaluedMap<String, String> map = createSRMap("PMRDP_SR_SERVEROP",
				srId, "Stop Server " + instance.hostName, "PMRDP_0257A_72");
		return postSR(map);
	}

	private void updateTerminateInstanceTicket(Instance instance, String srId,
			Ticket ticket) throws TSAMWebServiceClientException {
		QueryParam param = new QueryParam(srId, ticket);
		param.addTicketSpec("PMRDPCLCPR_SERVICEINSTANCEID", "NUMVALUE",
				instance.serviceInstanceId);
		param.addTicketSpec("PMRDPCLVSRV_MPNUM", "ALNVALUE", "DELSERVER");
		param.addTicketSpec("PMRDPCLCVS_VSNODEID", "NUMVALUE",
				instance.instanceId);
		postUpdateTicket(ticket, param);
	}

	public void terminateInstance(String instanceId)
			throws TSAMWebServiceClientException {
		Instance instance = obtainInstanceInfo(instanceId);
		String srId = createSR("Remove Server " + instance.hostName);
		Ticket ticket = updateTerminateInstanceSR(instance, srId);
		updateTerminateInstanceTicket(instance, srId, ticket);
	}

}
